package org.zn.note.designpattern;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 过滤器模式（Filter Pattern）或标准模式（Criteria Pattern）
 */
public class Pattern08_Filter {

    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("Robert", "Male", "Single"));
        persons.add(new Person("John", "Male", "Married"));
        persons.add(new Person("Laura", "Female", "Married"));
        persons.add(new Person("Diana", "Female", "Single"));
        persons.add(new Person("Mike", "Male", "Single"));
        persons.add(new Person("Bobby", "Male", "Single"));
        Criteria criteria = new AndCriteriaList(
                Arrays.asList(
                        new CriteriaMale(),
                        new CriteriaSingle()));
        List<Person> l = criteria.meetCriteria(persons);
        System.out.println(l);
    }

    // 标准：输入列表 --- 根据标准过滤 ---> 输出列表
    private interface Criteria {
        List<Person> meetCriteria(List<Person> persons);
    }

    // 标准：男人
    private static class CriteriaMale implements Criteria {
        @Override
        public List<Person> meetCriteria(List<Person> persons) {
            List<Person> malePersons = new ArrayList<>();
            for (Person person : persons) {
                if (person.getGender().equalsIgnoreCase("MALE")) {
                    malePersons.add(person);
                }
            }
            return malePersons;
        }
    }

    // 标准：单身
    private static class CriteriaSingle implements Criteria {
        @Override
        public List<Person> meetCriteria(List<Person> persons) {
            List<Person> singlePersons = new ArrayList<>();
            for (Person person : persons)
                if (person.getMaritalStatus().equalsIgnoreCase("SINGLE"))
                    singlePersons.add(person);
            return singlePersons;
        }
    }

    private static class AndCriteriaList implements Criteria {
        private List<Criteria> criterias;
        AndCriteriaList(List<Criteria> criterias) {
            this.criterias = criterias;
        }
        @Override
        public List<Person> meetCriteria(List<Person> persons) {
            List<Person> p = persons;
            for(Criteria criteria : criterias)
                p = criteria.meetCriteria(p);
            return p;
        }
    }

    private static class Person {

        private String name;
        private String gender;
        private String maritalStatus;

        public Person(String name, String gender, String maritalStatus) {
            this.name = name;
            this.gender = gender;
            this.maritalStatus = maritalStatus;
        }

        public String getName() {
            return name;
        }

        public String getGender() {
            return gender;
        }

        public String getMaritalStatus() {
            return maritalStatus;
        }
    }
}
